<template>
    <div class="box">
        <h1>组件间通信9: vuex</h1>
        <h2>未开启模块化</h2>
        <div>str: {{ $store.state.str }}</div>
        <div>str: {{ str }}</div>
        <div>moreStr: {{ $store.getters.moreStr }}</div>
        <div>moreStr: {{ moreStr }}</div>
        <button @click="$store.dispatch('changeStr', '我爱你,杨幂')">修改vuex中数据</button>
        <button @click="changeStr('我爱你,高圆圆')">修改vuex中数据</button>
        <br>
        <div>
            <p>一般情况下,不会直接把 mutations 拿过来调用,但是可以这么操作</p>
            <p>mutaions存在的意义就是为了让actions调用</p>
            <p>mutaions中不能有异步、if、for等语句,而actions中可以有</p>
        </div>
        <button @click="$store.commit('SET_STR', '我爱你,胡歌')">使用mutations修改str</button>
        <button @click="SET_STR('我爱你,王凯')">使用mutations修改str</button>
        <h2>----------------</h2>
        <Child1 />
        <Child2 />
    </div>
</template>

<script>
// vuex
// 一、什么情况下会使用vuex?
// 当多个组件依赖同一个数据的时候使用vuex
// 二、步骤:
//  1. 安装
//      npm i vuex@3
//  2. 引用使用 - src/store/index.js
//      import Vue from 'vue'
//      import Vuex from 'vuex'
//      Vue.use(Vuex)
//  3. 创建并暴露一个store
//      export default new Vuex.Store({ state, mutations, actions, getters })
//  4. 在创建vm的时候,挂上store
//      import store from '@/store/index.js'
//      new Vue({
//          store,
//          ...
//      })
// 三、四个核心配置项 - state, mutations, actions, getters
// 1. 未开启模块化 - 在new Vuex.Store({}) 直接写四个核心概念,就是没有开启模块化
//      每个核心概念都有两种使用方式: 普通使用 和 辅助函数(映射函数)
//      state
//          普通使用
//              $store.state.str
//          辅助函数使用
//              ...mapState(['str'])
//      getters
//          普通使用
//              $store.getters.moreStr
//          辅助函数使用
//              ...mapGetters(['moreStr'])
//      actions
//          普通使用
//              $store.dispatch('changeStr', 参数)
//          辅助函数使用
//              ...mapActions(['changeStr'])
//              调用: this.changeStr(参数)
//      mutations
//          普通使用
//              $store.commit('SET_STR', 参数)
//          辅助函数使用
//              ...mapMutations(['SET_STR'])
//              调用: this.SET_STR(参数)
//    未开启模块化的使用方式
//          注意: state 和 getters 映射到组件中的时候,要映射到 computed 中
//                actions 和 mutations 映射到组件中的时候,要映射到 methods 中
// 2. 开启模块化 - 为了防止使 state 中有重名的
//      创建一个小的store的js文件,在 src/store/modules/test.js
//      引入 src/store/index.js 中store配置项的 modules 中
//      state
//          普通使用
//              $store.state.test.count
//          辅助函数使用
//              ...mapState({
//                  count: state => state.test.count
//              })
//      getters
//          普通使用
//              $store.getters.tenflodCount
//          辅助函数使用
//              ...mapGetters(['tenflodCount'])
//      actions
//          普通使用
//              $store.dispatch('increment', 参数)
//          辅助函数使用
//              ...mapActions(['increment'])
//              调用: this.increment(参数)
//      mutations
//          普通使用
//              $store.commit('ADD', 参数)
//          辅助函数使用
//              ...mapMutations(['ADD'])
//              调用: this.ADD(参数)
// 3. 开启命名空间 - 在模块化的基础上,为了防止mutations和actions和getters 之间有重名而设立的
//      创建一个小store的js文件 src/store/modules/testspace.js
//      引入 src/store/index.js 中store配置项的 modules 中
//      注意: 小store中需要配置 namespaced: true 来开启命名空间
//      state
//          state的使用方式和开启模块化的时候使用方式一摸一样
//      getters
//          普通使用
//              $store.getters['testspace/tenflodCount']
//          辅助函数使用
//              ...mapGetters('testspace', ['tenflodCount'])
//              调用: this.tenflodCount
//      actions
//          普通使用
//              $store.dispatch('testspace/increment', 参数)
//          辅助函数使用
//              ...mapActions('testspace', ['increment'])
//              调用: this.increment(参数)
//      mutations
//          普通使用
//              $store.commit('testspace/ADD', 参数)
//          辅助函数使用
//              ...mapMutations('testspace', ['ADD'])
//              调用: this.ADD(参数)
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
import Child1 from './Child1.vue'
import Child2 from './Child2.vue'
export default {
    name: 'VuexTest',
    components: {
        Child1,
        Child2,
    },
    computed: {
        ...mapState(['str']),
        ...mapGetters(['moreStr']),
    },
    methods: {
        ...mapActions(['changeStr']),
        ...mapMutations(['SET_STR'])
    }
}
</script>

<style scoped>
</style>
